import React, { ReactNode, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
  Box,
  CounterCard,
  Empty,
  Grid,
  GridItem,
  Icon,
  IconButton,
  makeToast,
  NotificationBanner,
  UsageCard,
  UsageCardStep,
} from '@nova-hf/ui';
import { MainColorType, ThemeColorType } from '@nova-hf/ui/umd/ts/src/styles/vars.css';
import Link from 'next/link';
import {
  Setting,
  UsageType,
  useDataRoamingRatesCollectionQuery,
  useSubscriptionSettingsQuery,
  useSubscriptionUsagePacksQuery,
  useUpdateSettingMutation,
} from 'typings/graphql';
import { formatPrice } from 'utils/helpers';

type AbroadProps = {
  subscriptionId: string;
  color?: MainColorType;
};

const Abroad = ({ subscriptionId, color = 'pink' }: AbroadProps) => {
  const { t } = useTranslation('subscriptions');

  const stepWrapper = useRef(null);
  const stepActive = useRef(null);

  const [allowUpsell, setAllowUpsell] = useState<Setting | null>(null);
  const [updateSetting, { loading: setAllowUpsellLoading }] = useUpdateSettingMutation();

  const {
    data: dataRoamingData,
    error: dataRoamingError,
    loading: dataRoamingLoading,
  } = useDataRoamingRatesCollectionQuery();

  const {
    data: settingsData,
    error: settingsError,
    loading: settingsLoading,
  } = useSubscriptionSettingsQuery({
    variables: {
      input: {
        subscriptionId: subscriptionId,
      },
    },
  });

  const isInternetAbroadEnabled = settingsData?.subscription?.settings?.find(
    (s) => s.settingId === 'INTERNETABROAD',
  );

  const isUsageAbroadEnabled = settingsData?.subscription?.settings?.find(
    (s) => s.settingId === 'FOREIGNROAMING',
  );

  const { data, error, loading } = useSubscriptionUsagePacksQuery({
    variables: {
      input: {
        subscriptionId: subscriptionId,
      },
    },
  });

  useEffect(() => {
    const settingStatus = settingsData?.subscription?.settings?.find(
      (s) => s.settingId === 'ENABLE_UPSELL_MOBILE_DATA',
    );

    if (settingStatus !== undefined) {
      setAllowUpsell(settingStatus);
    }
  }, [settingsData]);

  if (error || dataRoamingError || settingsError) {
    return (
      <Empty icon="search" title={t('abroad.errorTitle')} subtitle={t('abroad.errorDescription')} />
    );
  }

  const renderUsageLoading = () => {
    return (
      <Box marginBottom={4}>
        <Grid rowGap={3} columnGap={3}>
          <GridItem gridColumn={{ sm: '1/4', md: '1/8', lg: '1/7' }}>
            <UsageCard
              withBorder
              color="grey500"
              title={t('abroad.internetAbroad')}
              progressBar={{
                percentage: 0,
                thickness: 2,
              }}
              price={{
                amount: 0,
              }}
              usage={{
                total: {
                  unit: '500 MB',
                },
                used: {},
                remaning: {
                  amount: t('abroad.inactive'),
                  isinfinite: false,
                },
              }}
            />
          </GridItem>
          <GridItem gridColumn={{ sm: '1/4', md: '1/8', lg: '8/12' }}>
            <CounterCard
              title={t('abroad.expiredCountdown')}
              color="grey500"
              date={new Date(travelDataServicePack?.validTo as Date)}
              height="100%"
            />
          </GridItem>
        </Grid>
      </Box>
    );
  };

  const renderStepsLoading = () => {
    return (
      <Box display="flex" overflow="auto" gap={5} marginBottom={3} paddingBottom={2}>
        <Box minWidth={[18, '3/12', '3/12']} flexGrow={1} position="relative">
          <UsageCardStep
            color={color}
            usage={{ amount: '500 MB' }}
            description={t('abroad.inactive')}
            isDisabled
          />
          <Box position="absolute" right={-4} top={4}>
            <Icon icon="longArrowRight" color={'grey400'} />
          </Box>
        </Box>
        <Box minWidth={[18, '3/12', '2/12']} position="relative">
          <UsageCardStep
            color={color}
            usage={{ amount: '2 GB' }}
            description={t('abroad.inactive')}
            isDisabled
          />
          <Box position="absolute" right={-4} top={4}>
            <Icon icon="longArrowRight" color={'grey400'} />
          </Box>
        </Box>
        <Box minWidth={[18, '3/12', '2/12']} position="relative">
          <UsageCardStep
            color={color}
            usage={{ amount: '5 GB' }}
            description={t('abroad.inactive')}
            isDisabled
          />
          <Box position="absolute" right={-4} top={4}>
            <Icon icon="longArrowRight" color={'grey400'} />
          </Box>
        </Box>
        <Box minWidth={[18, '3/12', '2/12']} position="relative">
          <UsageCardStep
            color={color}
            usage={{ amount: '10 GB' }}
            description={t('abroad.inactive')}
            isDisabled
          />
        </Box>
      </Box>
    );
  };

  const firstPack = data?.subscription?.packs?.find((pack) => pack !== undefined);

  const travelDataServicePack = data?.subscription?.packs?.find(
    (pack) => pack?.items?.find((item) => item.type === UsageType.TravelData),
  );
  const creditServicePack = data?.subscription?.packs?.find(
    (pack) => pack?.items?.find((item) => item.type === UsageType.Credit),
  );
  const eesServicePack = data?.subscription?.packs?.find(
    (pack) => pack?.items?.find((item) => item.type === UsageType.RoamLikeHome),
  );

  const travelDataUsage =
    travelDataServicePack?.items &&
    travelDataServicePack?.items.find((x) => x.type === UsageType.TravelData);
  const creditUsage =
    creditServicePack?.items && creditServicePack?.items.find((x) => x.type === UsageType.Credit);
  const eesUsage =
    eesServicePack?.items && eesServicePack?.items.find((x) => x.type === UsageType.RoamLikeHome);

  if (
    loading ||
    dataRoamingLoading ||
    settingsLoading ||
    !data?.subscription ||
    !data?.subscription?.packs
  ) {
    return (
      <>
        {renderUsageLoading()}
        {renderStepsLoading()}
      </>
    );
  }

  const allowUpsellClick = async () => {
    try {
      const { data: updateSettingData } = await updateSetting({
        variables: {
          input: {
            subscriptionId,
            settingId: allowUpsell?.settingId ?? '',
            on: !allowUpsell?.on,
          },
        },
      });

      if (updateSettingData?.updateSetting?.setting) {
        setAllowUpsell(updateSettingData?.updateSetting?.setting);
        makeToast.success(t('general.message.success'), '');
      } else {
        makeToast.danger(t('general.message.error'), '');
      }
    } catch (e) {
      if (e instanceof Error)
        makeToast.danger(t('general.message.error', { error: e.message }), '');
    }
  };

  const lastForeignZone = travelDataServicePack
    ? travelDataServicePack.lastForeignZone
    : firstPack?.lastForeignZone;

  const dataRoamingDataRates = dataRoamingData?.dataRoamingRatesCollection?.items?.find(
    (c) => c?.categoryId === lastForeignZone,
  );

  const activeDataRoamingSizeIndex =
    dataRoamingDataRates?.dataRoamingStepsCollection?.items.findIndex(
      (item) => travelDataUsage?.included?.text?.trim() === item?.stepText?.trim(),
    );

  const isZone5NoTravelData =
    activeDataRoamingSizeIndex === -1 &&
    !travelDataServicePack &&
    !travelDataUsage &&
    lastForeignZone === 5;

  const showEES = eesUsage && !travelDataServicePack && !travelDataUsage && !isZone5NoTravelData;

  const remainingTravelDataPercentage = () => {
    if (travelDataUsage?.infinite) return 100;
    if (travelDataUsage?.usage?.amount && travelDataUsage?.included?.amount) {
      return Math.round(
        100 - (travelDataUsage?.usage?.amount / travelDataUsage?.included?.amount) * 100,
      );
    } else return 0;
  };

  const remainingEESPercentage = () => {
    if (eesUsage?.infinite) return 100;
    if (eesUsage?.remaining?.amount && eesUsage?.included?.amount) {
      return Math.round((eesUsage?.remaining?.amount / eesUsage?.included?.amount) * 100);
    } else return 0;
  };

  const buttonColorsThatHaveBlackText: ThemeColorType[] = ['white', 'grey200', 'ocean', 'yellow'];
  const iconColor: ThemeColorType = buttonColorsThatHaveBlackText.includes(color)
    ? 'black100'
    : 'white';

  return (
    <>
      <Box marginBottom={4}>
        {((isInternetAbroadEnabled && !isInternetAbroadEnabled.on) ||
          (isUsageAbroadEnabled && !isUsageAbroadEnabled.on)) && (
          <Box marginBottom={4}>
            <NotificationBanner
              color={color}
              eyebrowText={t('abroad.internetAbroad')}
              icon="internet"
              mainButtonColored={{
                icon: 'longArrowRight',
                text: t('abroad.activate'),
                wrapper: (link: ReactNode) => (
                  <Link
                    href={`/thjonusta/${subscriptionId}/stillingar/utlond`}
                    passHref
                    legacyBehavior
                  >
                    {link}
                  </Link>
                ),
              }}
              title={t('abroad.activateInternetAbroad')}
            />
          </Box>
        )}

        {creditUsage && travelDataServicePack && travelDataUsage && (
          <Box marginBottom={4}>
            <UsageCard
              withBorder
              color={color}
              title={creditUsage?.title ?? ''}
              progressBar={{
                percentage: 100,
                thickness: 2,
              }}
              price={{
                amount: t('monthlyUsageSummary.total'),
              }}
              usage={{
                total: {
                  amount: creditUsage?.included?.amount ?? '',
                  unit: creditUsage?.included?.unit ?? 'kr.',
                },
                used: {},
                remaning: {},
              }}
            />
          </Box>
        )}
        {travelDataServicePack && travelDataUsage && (
          <Grid rowGap={3} columnGap={3}>
            <GridItem gridColumn={{ sm: '1/4', md: '1/8', lg: '1/7' }}>
              <UsageCard
                withBorder
                color={color}
                title={travelDataUsage?.title ?? ''}
                progressBar={{
                  percentage: remainingTravelDataPercentage(),
                  thickness: 2,
                }}
                price={{
                  amount:
                    activeDataRoamingSizeIndex || activeDataRoamingSizeIndex === 0
                      ? dataRoamingDataRates?.dataRoamingStepsCollection?.items[
                          activeDataRoamingSizeIndex
                        ]?.price
                      : 0,
                  unit: t('abroad.eachDay'),
                }}
                usage={{
                  total: {
                    amount: travelDataUsage?.included?.amount ?? '',
                    description: travelDataUsage?.included?.text ?? '',
                    unit: travelDataUsage?.included?.unit ?? 'MB',
                    isinfinite: travelDataUsage?.infinite || false,
                  },
                  used: {
                    amount: travelDataUsage?.usage?.amount ?? '',
                    description: t('usageSummary.usedDescription'),
                    unit: travelDataUsage?.usage?.unit ?? '',
                  },
                  remaning: {
                    amount: travelDataUsage?.remaining?.amount ?? '',
                    description: t('usageSummary.remainingDescription'),
                    unit: travelDataUsage?.remaining?.unit ?? '',
                    isinfinite: travelDataUsage?.infinite || false,
                  },
                }}
              />
            </GridItem>
            {travelDataServicePack?.validTo && (
              <GridItem gridColumn={{ sm: '1/4', md: '1/8', lg: '8/12' }}>
                <CounterCard
                  title={t('abroad.expiredCountdown')}
                  color={color}
                  date={new Date(travelDataServicePack?.validTo)}
                  height="100%"
                />
              </GridItem>
            )}
          </Grid>
        )}

        {showEES && (
          <Box marginBottom={4}>
            <UsageCard
              withBorder
              color={color}
              title={eesUsage?.title ?? ''}
              progressBar={{
                percentage: remainingEESPercentage(),
                thickness: 2,
              }}
              price={{
                amount: t('usageSummary.priceAmountLabel'),
              }}
              usage={{
                total: {
                  amount: eesUsage?.included?.amount ?? '',
                  description: eesUsage?.included?.text ?? '',
                  unit: eesUsage?.included?.unit ?? 'MB',
                  isinfinite: eesUsage?.infinite || false,
                },
                used: {
                  amount: eesUsage?.usage?.amount ?? '0',
                  description: t('usageSummary.usedDescription'),
                  unit: eesUsage?.usage?.unit ?? 'MB',
                },
                remaning: {
                  amount: eesUsage?.remaining?.amount ?? '',
                  description: t('usageSummary.remainingDescription'),
                  unit: eesUsage?.remaining?.unit ?? '',
                  isinfinite: eesUsage?.infinite || false,
                },
              }}
            />
          </Box>
        )}

        {!showEES && !travelDataServicePack && !travelDataUsage && renderUsageLoading()}
      </Box>

      {dataRoamingDataRates?.dataRoamingStepsCollection?.items &&
      activeDataRoamingSizeIndex !== undefined &&
      (activeDataRoamingSizeIndex !== -1 || isZone5NoTravelData) ? (
        <Box
          ref={stepWrapper}
          display="flex"
          overflow="auto"
          gap={5}
          marginBottom={3}
          paddingBottom={2}
        >
          {dataRoamingDataRates?.dataRoamingStepsCollection?.items.map((item, i, list) => {
            const isStepActive = activeDataRoamingSizeIndex === i;
            const isStepEmpty = activeDataRoamingSizeIndex > i;
            const isStepNext = activeDataRoamingSizeIndex + 1 === i;
            const isStepBigger = activeDataRoamingSizeIndex < i;

            return (
              <Box
                key={item?.stepText}
                {...(isStepActive && { ref: stepActive })}
                flexGrow={isStepActive ? 1 : 0}
                minWidth={isStepActive ? [24, '4/12', '3/12'] : [18, '3/12', '2/12']}
                position="relative"
              >
                <UsageCardStep
                  color={color}
                  usage={{ amount: item?.stepText }}
                  isActive={isStepActive}
                  description={
                    (isStepEmpty && t('abroad.used')) || (isStepActive && t('abroad.active'))
                  }
                  isDisabled={isStepEmpty}
                  price={isStepActive || isStepBigger ? formatPrice(item?.price as number) : ''}
                />
                {allowUpsell &&
                  !allowUpsell?.on &&
                  isStepNext &&
                  settingsData &&
                  !settingsError &&
                  !settingsLoading && (
                    <IconButton
                      renderAs="button"
                      hiddenButtonText={t('abroad.activate')}
                      icon="lockOpen"
                      color={iconColor}
                      isLoading={setAllowUpsellLoading}
                      wrapper={(link) => (
                        <Box
                          renderAs="button"
                          onClick={allowUpsellClick}
                          display="flex"
                          justifyContent="center"
                          alignItems="center"
                          width="100%"
                          background={color}
                          padding={1}
                        >
                          {link}
                        </Box>
                      )}
                    />
                  )}
                {i + 1 !== list.length && (
                  <Box position="absolute" right={-4} top={4}>
                    <Icon
                      icon="longArrowRight"
                      color={
                        isStepActive && (allowUpsell?.on || allowUpsell === null)
                          ? color
                          : 'grey400'
                      }
                    />
                  </Box>
                )}
              </Box>
            );
          })}
        </Box>
      ) : (
        !showEES && renderStepsLoading()
      )}
    </>
  );
};
export default Abroad;
